package com.shuangseqiu.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author: zm
 * @data 2025-10-25- 15:46
 */
public class baseServiceImpl {
    private static final Logger logger = LoggerFactory.getLogger(LeCaiServiceImpl.class);

    // 匹配彩票号码的正则表达式（红球：1-33，蓝球：1-16）
    private static final Pattern RED_BALL_PATTERN = Pattern.compile("(?:红球|胆码|推荐).*?((?:[1-9]|[12]\\d|3[0-3])(?:[,，、\\D]+(?:[1-9]|[12]\\d|3[0-3])){5,})");
    private static final Pattern BLUE_BALL_PATTERN = Pattern.compile("(?:蓝球|蓝号).*?([1-9]|1[0-6])");
    private static final Pattern NUMBER_PATTERN = Pattern.compile("(?:[1-9]|[12]\\d|3[0-3]|[1-9]|1[0-6])");
    private static final Pattern PERIOD_PATTERN = Pattern.compile("(\\d{5,8})");


    private static final  Pattern numberPattern = Pattern.compile("\\d{1,3}");

    @Autowired
    private HttpService httpService;

    @Autowired
    private ObjectMapper objectMapper;

    @Value("${prediction.data.path:./data}")
    public String dataPath;




    /**
     * 判断是否为预测文章链接
     */
    public boolean isPredictionArticleLink(String url, String text, String period) {
        // 包含双色球、预测、分析等关键词的链接
        String lowerText = text.toLowerCase();
        String lowerUrl = url.toLowerCase();

        // boolean isPrediction = lowerText.contains("双色球");
        // &&
//                              (lowerText.contains("预测") ||
//                               lowerText.contains("分析") ||
//                               lowerText.contains("推荐"));

        boolean hasPeriod = text.contains(period) || url.contains(period);

        // 过滤掉无关链接
//        boolean isUseful =  !lowerUrl.contains("login") &&
//                           !lowerUrl.contains("register") &&
//                           !lowerUrl.contains("javascript:") &&
//                           url.startsWith("http");

        return hasPeriod;// (isPrediction || hasPeriod) ;// && isUseful;
    }


    /**
     * @author zm
     * @date 2025/10/19 11:25
     * @desc 整体分析，推荐：号码
     **/
    public boolean extractTongYongNumbers(Element element, Map<String, Object> result,String period) {
        List<String> resultR = new ArrayList<>();
        List<String> resultB = new ArrayList<>();
        Elements paragraphs = element.select("p");
        boolean isPiPei = false;

        // 匹配 **** + *** 这种模式
        // 定义正则表达式匹配模式，捕获加号前的数字序列
        Pattern patternA = Pattern.compile("(?:红球.*?推荐|蓝球.*?推荐|蓝.*?胆|红.*?胆|蓝.*?码|红.*?码|.*?围蓝).{0,2}\\D{0,8}\\D((\\d{1,2}[\\D&&[^+]]*)+)");
        //Pattern patternB = Pattern.compile("([^+]*?)((?:\\d{1,2}[\\D&&[^+]]*)+)\\+\\D?((?:\\d{1,2}[\\D&&[^+]]*)+)");
        for (Element paragraph : paragraphs) {
            String text = paragraph.text();
            //排除上期
            if ((text.contains("上")|| text.contains("期"))&&( !text.contains(period))) {
                continue;
            }
            if(text.contains("杀")){
                continue;
            }

            // Matcher matcherB = patternB.matcher(paragraph.text());
            if (text.contains("+")) {
                isPiPei = true;
                // 清理数字序列中的空格和非数字字符
                logger.info("匹配规则【通用匹配 红 红 红 + 蓝 蓝】》》{}", text);
                String[] split = text.split("\\+");
                //红球部分
                logger.info("红球部分：{}",split[split.length-2]);

                Matcher numberMatcher = numberPattern.matcher(split[split.length-2]);
                // 按两位数字分组
                while (numberMatcher.find()) {
                    String number = numberMatcher.group();
                    // 处理每个号码
                    int num = Integer.parseInt(number);
                    if (num >= 1 && num <= 33) {
                        String format = String.format("%02d", num);
                        resultR.add(format);
                    }
                }
                //蓝球部分
                String blueStr = split[split.length-1];
                logger.info("蓝球部分：{}",blueStr);
                Matcher numberMatcherB = numberPattern.matcher(blueStr);
                // 按两位数字分组
                while (numberMatcherB.find()) {
                    String number = numberMatcherB.group();
                    // 处理每个号码
                    int num = Integer.parseInt(number);
                    if (num >= 1 && num <= 33) {
                        String format = String.format("%02d", num);
                        resultB.add(format);
                    }
                }
            }
            Matcher matcherA = patternA.matcher(text);
            while (matcherA.find()) {
                if(text.contains("杀")){
                    logger.info("匹配规则【杀】》》{}", matcherA.group());
                    break;
                }
                isPiPei = true;
                logger.info("匹配规则【通用匹配 红球推荐|蓝球推荐 球】》》{}", matcherA.group());
                String qiuleixing = matcherA.group(0);
                String numbersPart = matcherA.group(1);
                Matcher numberMatcher = numberPattern.matcher(numbersPart);
                while (numberMatcher.find()) {
                    String number = numberMatcher.group();
                    // 处理每个号码
                    int num = Integer.parseInt(number);
                    if (num >= 1 && num <= 33) {
                        String format = String.format("%02d", num);
                        if (qiuleixing.contains("蓝")) {
                            resultB.add(format);
                        } else {
                            resultR.add(format);
                        }
                    }
                }
            }
        }

        if(isPiPei){
            result.put("redBalls", resultR);
            result.put("blueBalls", resultB);
        }
        return isPiPei;
    }


    /**
     * @author zm
     * @date 2025/10/19 11:25
     * @desc 整体分析，推荐：号码
     **/
    public List<String> extractTuiJianNumbers(Element element,String period) {
        List<String> result = new ArrayList<>();
        Pattern pattern = Pattern.compile("(?:推荐|建议|精髓|必中).{0,2}\\D{0,8}\\D((?:\\d{1,2}\\D{0,2})+)$");
        Elements paragraphs = element.select("p");
        for (Element paragraph : paragraphs) {
            String text = paragraph.text();
            //排除上期
            if ((text.contains("上")|| text.contains("期"))&&( !text.contains(period))) {
                continue;
            }
            if(text.contains("杀")||text.contains("区间")||text.contains("奇偶比")||text.contains("大小比")||text.contains("质合比")||text.contains("比例")||text.contains("和值")||text.contains("和值")){
                continue;
            }

            Matcher matcher = pattern.matcher(text);
            while (matcher.find()) {
                logger.info("匹配规则【推荐|建议 球】》》{}", matcher.group());
                String numbersPart = matcher.group(1);


                Matcher numberMatcher = numberPattern.matcher(numbersPart);
                while (numberMatcher.find()) {
                    String number = numberMatcher.group();
                    // 处理每个号码
                    int num = Integer.parseInt(number);
                    if (num >= 1 && num <= 33) {
                        String format = String.format("%02d", num);
                        result.add(format);
                    }
                }
            }
        }
        logger.info("匹配规则【*** 推荐|建议 球】》》{}", result);
        return result;
    }

    /**
     * 提取红球号码
     *
     * @param text 包含红球号码的文本
     * @return 格式化后的红球号码列表，按升序排列
     */
    public List<String> extractRedBalls(String text) {
        Set<String> balls = new HashSet<>();


        // 匹配形式  景天枫：01,05,16,17,22,25,27,30,33+05,13,14 加号前面的数字，分别计数，数字个数不定
        extractRedNumbersA(text,balls);
        // 匹配形式 红球龙头热点：03 05
        extractRedNumbersB(text,balls);
        return balls.stream().sorted().collect(Collectors.toList());
    }



    /**
     * 从输入字符串中提取加号前的数字序列，并按两位数字分组
     * 匹配形式  景天枫：01,05,16,17,22,25,27,30,33+05,13,14 加号前面的数字，分别计数，数字个数不定
     * @param inputStr 输入字符串
     * @return 两位数字分组的列表
     */
    public List<String> extractRedNumbersA(String inputStr,Set<String> balls) {

        List<String> result = new ArrayList<>();
        // 定义正则表达式匹配模式，捕获加号前的数字序列
        Pattern pattern = Pattern.compile("([^+]*?)((\\d+[\\D&&[^+]]*)+)\\+");
        Matcher matcher = pattern.matcher(inputStr);

        if (matcher.find()) {
            // 清理数字序列中的空格和非数字字符
            String numbersPart = matcher.group(2);

            Matcher numberMatcher = numberPattern.matcher(numbersPart);
            while (numberMatcher.find()) {
                String number = numberMatcher.group();
                // 处理每个号码
                int num = Integer.parseInt(number);
                if (num >= 1 && num <= 33) {
                    String format = String.format("%02d", num);
                    balls.add(format); // 格式化为两位数字
                    result.add(format);
                }
            }

            logger.info("匹配规则【红,红+蓝，蓝蓝】：{} 红球 》》{}", inputStr,result);
        }
        return result;
    }

    /**
     * @author zm
     * @date 2025/10/19 11:25
     * @desc 匹配格式 红球龙头热点：03 05
     **/
    public Collection<String> extractRedNumbersB(String text, Set<String> balls) {
        List<String> result = new ArrayList<>();
        Pattern pattern = Pattern.compile("红球.*?\\D((?:\\d{1,2}\\D*)+)");
        Matcher matcher = pattern.matcher(text);
        if (matcher.find()) {
            String numbersPart = matcher.group(1);

            Matcher numberMatcher = numberPattern.matcher(numbersPart);
            while (numberMatcher.find()) {
                String number = numberMatcher.group();
                // 处理每个号码
                int num = Integer.parseInt(number);
                if (num >= 1 && num <= 33) {
                    String format = String.format("%02d", num);
                    balls.add(format); // 格式化为两位数字
                    result.add(format);
                }
            }

            logger.info("匹配规则【红球***： 红球】： {}  红球》》{}", text,result);
        }
        return result;
    }

    /**
     * 提取蓝球号码
     */
    public List<String> extractBlueBalls(String text) {
        Set<String> balls = new HashSet<>();
        // 匹配形式   01,05,16,17,22,25,27,30,33+05,13,14 加号后面的数字，分别计数，数字个数不定
        extractBlueNumbersA(text,balls);
        // 匹配形式 蓝球**：03 05
        extractBlueNumbersB(text,balls);
        return balls.stream().sorted().collect(Collectors.toList());
    }

    /**
     * 从输入字符串中提取加号前的数字序列，并按两位数字分组
     * 匹配形式  景天枫：01,05,16,17,22,25,27,30,33+05,13,14 加号后面的数字，分别计数，数字个数不定
     * @param inputStr 输入字符串
     * @return 两位数字分组的列表
     */
    public List<String> extractBlueNumbersA(String inputStr,Set<String> balls) {

        List<String> result = new ArrayList<>();
        // 定义正则表达式匹配模式，捕获加号后的数字序列
        Pattern pattern = Pattern.compile("\\+\\D?((\\d+[\\D&&[^+]]*)+)");
        Matcher matcher = pattern.matcher(inputStr);

        if (matcher.find()) {
            // 清理数字序列中的空格和非数字字符
            String numbersPart = matcher.group(1);

            Matcher numberMatcher = numberPattern.matcher(numbersPart);
            while (numberMatcher.find()) {
                String number = numberMatcher.group();
                // 处理每个号码
                int num = Integer.parseInt(number);
                if (num >= 1 && num <= 33) {
                    String format = String.format("%02d", num);
                    balls.add(format); // 格式化为两位数字
                    result.add(format);
                }
            }

            logger.info("匹配规则【红,红+蓝，蓝蓝】：{} 蓝球 》》{}", inputStr,result);
        }
        return result;
    }

    /**
     * @author zm
     * @date 2025/10/19 11:25
     * @desc 匹配格式 蓝球龙头热点：03 05
     **/
    public Collection<String> extractBlueNumbersB(String text, Set<String> balls) {
        List<String> result = new ArrayList<>();
        Pattern pattern = Pattern.compile("蓝球.*?\\D((?:\\d{1,2}\\D*)+)");
        Matcher matcher = pattern.matcher(text);
        if (matcher.find()) {
            String numbersPart = matcher.group(1);
            Matcher numberMatcher = numberPattern.matcher(numbersPart);
            while (numberMatcher.find()) {
                String number = numberMatcher.group();
                // 处理每个号码
                int num = Integer.parseInt(number);
                if (num >= 1 && num <= 33) {
                    String format = String.format("%02d", num);
                    balls.add(format); // 格式化为两位数字
                    result.add(format);
                }
            }

            logger.info("匹配规则【蓝球***： 蓝球】：{} 蓝球 》》{}", text, result);
        }
        return result;
    }

    /**
     * 更新号码统计信息
     */
    public void updateNumberStats(List<String> numbers, String type, String articleTitle,
                                  Map<String, Integer> numberCountMap,
                                  Map<String, List<String>> numberToArticlesMap) {
        for (String number : numbers) {
            String key = number;
            // 更新计数
            numberCountMap.put(key, numberCountMap.getOrDefault(key, 0) + 1);
            // 更新关联文章
            //numberToArticlesMap.computeIfAbsent(key, k -> new ArrayList<>()).add(articleTitle);
        }
    }

    /**
     * 按预测文章数量倒序排序号码
     */
    public List<Map<String, Object>> sortNumbersByCount(Map<String, Integer> numberCountMap,boolean isBlue ) {
        // 按numberCountMap的value数量倒序排序，并加上排名
        List<Map<String, Object>> sortedList = new ArrayList<>();
        int rank = 1;

        for (Map.Entry<String, Integer> entry : numberCountMap.entrySet().stream()
                .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                .collect(Collectors.toList())) {
            try {
                if (isBlue && Integer.parseInt(entry.getKey()) > 16) {
                    continue;
                }
                Map<String, Object> item = new HashMap<>();
                item.put("key", entry.getKey());
                item.put("value", entry.getValue());
                item.put("rank", rank++);
                sortedList.add(item);
            }catch (Exception ex){
                logger.error("排序异常",ex.getMessage());
            }
        }
        return sortedList;
    }
}
